home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_500
/
wiconify
/
wiconify-source.lzh
/
Source
/
wIconify.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
22KB
|
660 lines
/*
* WICONIFY A utility that allows you to iconify any Intuition window
* on any screen, and to open WB windows on any screen.
*
* wIconify.c Main loader code.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include <intuition/intuitionbase.h>
#include <devices/input.h>
#include "wIconify.h"
#include "wSetup.h"
#include "wMenu.h"
#include <libraries/dosextens.h>
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
struct LayersBase *LayersBase;
extern struct SysBase *SysBase;
extern struct DOSBase *DOSBase;
static char *program = PROGRAM;
static char *copyright = COPYRIGHT;
static char *handler = HANDLERCODE2; /* The name of the handler file */
static char *HANDLER = HANDLERCODE1;
static char *InitFile = INITFILENAME2; /* the Init file */
static char *INITFILE = INITFILENAME1;
#define DEFAULTCOMMAND "NEWSHELL" /* the default CLI command */
#define K *1024 /* for things like 2K */
static struct HandlerData *HandlerData; /* data shared with handler */
static long Segment; /* The loaded handler segment */
static APTR HandlerTask; /* The process created */
static struct MsgPort *InputPort; /* To talk to Input.Device */
static struct IOStdReq *InputBlock; /* IO block for Input.Device */
static int InputDevice; /* Is Input.Device open? */
static int VectorsSet; /* TRUE after SetFunction */
static int HandlerAdded; /* TRUE after TellInputDevice */
static int AllOK; /* TRUE after ActivateIconify */
#define vSETFUNC(lvo,func) SetFunction(IntuitionBase,&lvo,var(func))
#define VSETFUNC(lvo,func) SetFunction(IntuitionBase,&lvo,VAR(func))
#define HANDLERPROC ((struct Process *)HandlerTask)
struct Menu *wMenuBar; /* The wIconify window's menu bar */
struct wMenuItem *OpenWindowMenu; /* the OpenOn sub-menu */
char *HiResCLICommand; /* The HIRES NewCLI command string */
char *LoResCLICommand; /* The LOWRES NewCLI command string */
long StackSize; /* The CLI command stack size */
struct Image *DefaultImage; /* Image for icons that don't give one */
struct Image *DefaultSelect; /* Select image for icons without one */
struct Image *DefaultMask; /* Default mask for Image or Select */
struct Image *DefaultScreenImage; /* Image for screens that don't give one */
struct Image *DefaultScreenSelect; /* Select image for screenss without one */
struct Image *DefaultScreenMask; /* Default mask for screen icons */
ULONG DefaultFlags; /* Icon flags default icons */
ULONG DefaultScreenFlags; /* Icon flags default screen icons */
struct Ignore *IgnoreScreen; /* List of screen titles to ignore */
UBYTE IconifyKey = WICONIFYKEY; /* Key for iconifying active window */
UBYTE ActivateKey = WACTIVEKEY; /* Key for activating wIconify window */
UWORD IconifyQuals = WQUALIFIERS; /* Qualifiers for iconifying a window */
UWORD IconifyDisquals; /* Qualifiers that prevent iconifying */
UWORD IconifyChange = WCHANGEQUALS; /* Qualifiers for changing refresh type */
UWORD ActivateQuals = WACTIVEQUAL; /* Qualifiers for activating wIconify */
int IconifyPriority; /* Priority of handler as a process */
int HandlerPriority = 51; /* Priority of Input Handler in chain */
UWORD *ScreenColors; /* Default New Screen color map */
int AutoResize = TRUE; /* Size windows to fit screen? */
int ScreenType = OW_ACTIVESCRN; /* Where to open WB windows */
/*
* SetWindowMenu()
*
* Set the menu flags for the OpenOn submenu so that the proper ones
* are checked.
*/
static void SetWindowMenu(ScreenType,SizeToFit)
int ScreenType,SizeToFit;
{
short i;
if (ScreenType != NOCHANGE)
{
for (i=OW_ACTIVESCRN; i<=OW_REALWB; i++)
{
if (i == ScreenType)
OpenWindowMenu[i].Item.Flags |= CHECKED;
else
OpenWindowMenu[i].Item.Flags &= ~CHECKED;
}
}
if (SizeToFit != NOCHANGE)
{
if (SizeToFit)
OpenWindowMenu[OW_AUTORESIZE].Item.Flags |= CHECKED;
else
OpenWindowMenu[OW_AUTORESIZE].Item.Flags &= ~CHECKED;
}
}
/*
* FreeImage()
*
* If the image is not the defualt image (which was not allocated dynamically),
* then free any image data bitplanes, and free the image structure itself.
*/
static void FreeImage(theImage)
struct Image *theImage;
{
if (theImage != var(DefaultIcon) && theImage != var(DefaultScreenIcon))
{
if (theImage->ImageData) FreeRaster(theImage->ImageData,
theImage->Width,theImage->Height*theImage->Depth);
FREESTRUCT(Image,theImage);
}
}
/*
* CleanUpDefaults()
*
* Free any allocated memory, specifically, the NewCLI strings, the
* default images, and the ignored-screen title list.
*/
static void CleanUpDefaults()
{
struct Ignore *nextIgnore;
if (HiResCLICommand) FREECHAR(HiResCLICommand);
if (LoResCLICommand) FREECHAR(LoResCLICommand);
if (DefaultImage) FreeImage(DefaultImage);
if (DefaultSelect) FreeImage(DefaultSelect);
if (DefaultMask) FreeImage(DefaultMask);
if (DefaultScreenImage) FreeImage(DefaultScreenImage);
if (DefaultScreenSelect) FreeImage(DefaultScreenSelect);
if (DefaultScreenMask) FreeImage(DefaultScreenMask);
while (IgnoreScreen)
{
nextIgnore = IgnoreScreen->Next;
if (IgnoreScreen->Title) FREECHAR(IgnoreScreen->Title);
FREESTRUCT(Ignore,IgnoreScreen);
IgnoreScreen = nextIgnore;
}
}
/*
* DoExit()
*
* General purpose error-exit routine. Print an error message if one was
* supplied (it can have up to three parameters), and then clean up any
* memory, libraries, etc. that need to be handled before exiting.
*/
void DoExit(s,x1,x2,x3)
char *s, *x1, *x2, *x3;
{
long status = EXIT_OK;
extern int UnSetVectors();
extern int TellInputDevice();
if (s != NULL)
{
printf(s,x1,x2,x3);
printf("\n");
status = EXIT_ERROR;
}
if (VectorsSet) if (!UnSetVectors())
printf("Fatal Error: Can't remove SetFunction Vectors!"),
Segment = NULL;
if (HandlerAdded)
{
HandlerAdded = FALSE;
if (!TellInputDevice(IND_REMHANDLER))
printf("Fatal Error: Can't remove Input Handler!"),
Segment = NULL;
}
if (HandlerTask)
{
Signal(HandlerTask,CANCELSIGNAL);
Wait(OKSIGNAL| CANCELSIGNAL);
}
if (!AllOK) CleanUpDefaults();
if (Segment) UnLoadSeg(Segment), printf("wIconify Removed\n");
if (InputDevice) CloseDevice(InputBlock);
if (InputBlock) DeleteStdIO(InputBlock);
if (InputPort) DeletePort(InputPort);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
if (LayersBase) CloseLibrary(LayersBase);
exit(status);
}
/*
* CheckLibOpen()
*
* Call OpenLibrary() for the specified library, and check that the
* open succeeded.
*/
static void CheckLibOpen(lib,name,rev)
APTR *lib;
char *name;
int rev;
{
extern APTR OpenLibrary();
if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
DoExit("Can't open %s",name);
}
/*
* TellInputDevice()
*
* Create a port and I/O block, then open the input device. Set up the
* I/O block to add or remove the input handler, and send the request
* to the input device. Finally, close the device and delete the
* I/O block and port.
*/
static int TellInputDevice(function)
int function;
{
long status;
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
if ((InputPort = CreatePort(NULL,0)) == NULL) return(FALSE);
if ((InputBlock = CreateStdIO(InputPort)) == NULL) return(FALSE);
InputDevice = (OpenDevice("input.device",0,InputBlock,0) == 0);
if (InputDevice == FALSE) return(FALSE);
InputBlock->io_Command = (long) function;
InputBlock->io_Data = (APTR) var(Handler_Interrupt);
if (status = DoIO(InputBlock)) return(FALSE);
CloseDevice(InputBlock); InputDevice = FALSE;
DeleteStdIO(InputBlock); InputBlock = NULL;
DeletePort(InputPort); InputPort = NULL;
return(TRUE);
}
/*
* SetDefaults()
*
* If the initialization file did not specify an iconify key or an
* activation key, set them to the defaults. Set the default image
* If none was given. Set the default HIRES command if none was
* provided. Check the Image and Select image sizes to see that they
* match, and give a warning of not.
*/
static void SetDefaults()
{
if (IconifyKey == 0)
{
IconifyKey = WICONIFYKEY;
IconifyQuals = WQUALIFIERS;
IconifyDisquals = 0;
}
if (ActivateKey == 0)
{
ActivateKey = WACTIVEKEY;
ActivateQuals = WACTIVEQUAL;
}
if (DefaultImage == NULL) DefaultImage = var(DefaultIcon);
if (DefaultScreenImage == NULL) DefaultScreenImage = var(DefaultScreenIcon);
if (HiResCLICommand == NULL)
{
if (NEWCHAR(HiResCLICommand,strlen(DEFAULTCOMMAND)))
strcpy(HiResCLICommand,DEFAULTCOMMAND);
}
if (DefaultSelect)
{
if (DefaultImage->Width != DefaultSelect->Width ||
DefaultImage->Height != DefaultSelect->Height)
printf("Warning: DEFAULT_IMAGE and DEFAULT_SELECT sizes don't match\n");
}
if (DefaultScreenSelect)
{
if (DefaultScreenImage->Width != DefaultScreenSelect->Width ||
DefaultScreenImage->Height != DefaultScreenSelect->Height)
printf("Warning: SCREEN_IMAGE and SCREEN_SELECT sizes don't match\n");
}
if (DefaultMask)
{
if (DefaultImage->Width != DefaultMask->Width ||
DefaultImage->Height != DefaultMask->Height)
{
printf("Error: DEFAULT_IMAGE and DEFAULT_MASK sizes don't match\n");
FreeImage(DefaultMask); DefaultMask = NULL;
}
}
if (DefaultScreenMask)
{
if (DefaultScreenImage->Width != DefaultScreenMask->Width ||
DefaultScreenImage->Height != DefaultScreenMask->Height)
{
printf("Error: SCREEN_IMAGE and SCREEN_MASK sizes don't match\n");
FreeImage(DefaultScreenMask); DefaultScreenMask = NULL;
}
}
if (StackSize == 0) StackSize = 8K; else
if (StackSize < 2K) StackSize = 2K;
var(Handler_Interrupt)->is_Node.ln_Pri = HandlerPriority;
}
/*
* SetVectors()
*
* Set the Intuition library vectors for the Intuition functions
* to the routines specified by the handler. Save the old routine
* pointers for later replacement.
*/
static void SetVectors()
{
VAR(OldOpenWindow) = vSETFUNC(LVOOpenWindow,aOpenWindow);
VAR(OldCloseWindow) = vSETFUNC(LVOCloseWindow,aCloseWindow);
VAR(OldOpenScreen) = vSETFUNC(LVOOpenScreen,aOpenScreen);
VAR(OldCloseScreen) = vSETFUNC(LVOCloseScreen,aCloseScreen);
VAR(OldSetWindowTitles) = vSETFUNC(LVOSetWindowTitles,aSetWindowTitles);
VAR(OldWindowToFront) = vSETFUNC(LVOWindowToFront,aWindowToFront);
VAR(OldWindowToBack) = vSETFUNC(LVOWindowToBack,aWindowToBack);
VAR(OldActivateWindow) = vSETFUNC(LVOActivateWindow,aActivateWindow);
VAR(OldBuildSysRequest) = vSETFUNC(LVOBuildSysRequest,aBuildSysRequest);
VAR(OldFreeSysRequest) = vSETFUNC(LVOFreeSysRequest,aFreeSysRequest);
VAR(OldAutoRequest) = vSETFUNC(LVOAutoRequest,aAutoRequest);
VectorsSet = TRUE;
}
/*
* UnSetVectors()
*
* Replace the old Intuition library vectors, but make sure that no one
* else has changed them behind our back. If they are not the same as
* what we set them to originally, then put back the ones that we found,
* and return an error status.
*/
static int UnSetVectors()
{
long NewOpenWindow,NewCloseWindow;
long NewOpenScreen,NewCloseScreen;
long NewSetWindowTitles;
long NewWindowToFront,NewWindowToBack,NewActivateWindow;
long NewBuildSysRequest,NewFreeSysRequest,NewAutoRequest;
int status = TRUE;
NewOpenWindow = VSETFUNC(LVOOpenWindow,OldOpenWindow);
NewCloseWindow = VSETFUNC(LVOCloseWindow,OldCloseWindow);
NewOpenScreen = VSETFUNC(LVOOpenScreen,OldOpenScreen);
NewCloseScreen = VSETFUNC(LVOCloseScreen,OldCloseScreen);
NewSetWindowTitles = VSETFUNC(LVOSetWindowTitles,OldSetWindowTitles);
NewWindowToFront = VSETFUNC(LVOWindowToFront,OldWindowToFront);
NewWindowToBack = VSETFUNC(LVOWindowToBack,OldWindowToBack);
NewActivateWindow = VSETFUNC(LVOActivateWindow,OldActivateWindow);
NewBuildSysRequest = VSETFUNC(LVOBuildSysRequest,OldBuildSysRequest);
NewFreeSysRequest = VSETFUNC(LVOFreeSysRequest,OldFreeSysRequest);
NewAutoRequest = VSETFUNC(LVOAutoRequest,OldAutoRequest);
if (NewOpenWindow != (long) var(aOpenWindow) ||
NewCloseWindow != (long) var(aCloseWindow) ||
NewOpenScreen != (long) var(aOpenScreen) ||
NewCloseScreen != (long) var(aCloseScreen) ||
NewSetWindowTitles != (long) var(aSetWindowTitles) ||
NewWindowToFront != (long) var(aWindowToFront) ||
NewWindowToBack != (long) var(aWindowToBack) ||
NewActivateWindow != (long) var(aActivateWindow) ||
NewBuildSysRequest != (long) var(aBuildSysRequest) ||
NewFreeSysRequest != (long) var(aFreeSysRequest) ||
NewAutoRequest != (long) var(aAutoRequest))
{
SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
SetFunction(IntuitionBase,&LVOCloseWindow,NewCloseWindow);
SetFunction(IntuitionBase,&LVOOpenScreen,NewOpenScreen);
SetFunction(IntuitionBase,&LVOCloseScreen,NewCloseScreen);
SetFunction(IntuitionBase,&LVOSetWindowTitles,NewSetWindowTitles);
SetFunction(IntuitionBase,&LVOWindowToFront,NewWindowToFront);
SetFunction(IntuitionBase,&LVOWindowToBack,NewWindowToBack);
SetFunction(IntuitionBase,&LVOActivateWindow,NewActivateWindow);
SetFunction(IntuitionBase,&LVOBuildSysRequest,NewBuildSysRequest);
SetFunction(IntuitionBase,&LVOFreeSysRequest,NewFreeSysRequest);
SetFunction(IntuitionBase,&LVOAutoRequest,NewAutoRequest);
VectorsSet = status = FALSE;
}
return(status);
}
/*
* GetVariables()
*
* Get copies of the Handler variables that the loader will need during
* the setup process.
*/
static void GetVariables()
{
wMenuBar = var(wMenu);
OpenWindowMenu = var(OpenWindowMenu);
ScreenColors = var(Colors);
}
/*
* SetVariables()
*
* Once the loader has does its initialization, set the variables
* required by the handler.
*/
static void SetVariables()
{
VAR(IntuitionBase) = IntuitionBase;
VAR(GfxBase) = GfxBase;
VAR(LayersBase) = LayersBase;
VAR(SysBase) = SysBase;
VAR(DOSBase) = DOSBase;
VAR(HiResCLICommand) = HiResCLICommand;
VAR(LoResCLICommand) = LoResCLICommand;
VAR(StackSize) = StackSize;
VAR(DefaultImage) = DefaultImage;
VAR(DefaultSelect) = DefaultSelect;
VAR(DefaultMask) = DefaultMask;
VAR(DefaultScreenImage) = DefaultScreenImage;
VAR(DefaultScreenSelect) = DefaultScreenSelect;
VAR(DefaultScreenMask) = DefaultScreenMask;
VAR(DefaultFlags) = DefaultFlags;
VAR(DefaultScreenFlags) = DefaultScreenFlags;
VAR(IgnoreScreen) = IgnoreScreen;
VAR(IconifyKey) = IconifyKey;
VAR(ActivateKey) = ActivateKey;
VAR(IconifyQuals) = IconifyQuals;
VAR(IconifyDisquals) = IconifyDisquals;
VAR(IconifyChange) = IconifyChange;
VAR(ActivateQuals) = ActivateQuals;
SetWindowMenu(ScreenType,AutoResize);
}
/*
* GetIconifyVars()
*
* When it comes time to remove the handler, recover the initialized
* data from the HandlerData structure, and set the flags so that cleanup
* will proceed properly.
*/
static void GetIconifyVars()
{
IntuitionBase = VAR(IntuitionBase);
GfxBase = VAR(GfxBase);
LayersBase = VAR(LayersBase);
HiResCLICommand = VAR(HiResCLICommand);
LoResCLICommand = VAR(LoResCLICommand);
DefaultImage = VAR(DefaultImage);
DefaultSelect = VAR(DefaultSelect);
DefaultMask = VAR(DefaultMask);
DefaultScreenImage = VAR(DefaultScreenImage);
DefaultScreenSelect = VAR(DefaultScreenSelect);
DefaultScreenMask = VAR(DefaultScreenMask);
IgnoreScreen = VAR(IgnoreScreen);
Segment = var(Segment);
VectorsSet = TRUE;
HandlerAdded = TRUE;
AllOK = FALSE;
HandlerTask = NULL;
}
/*
* LoadIconify()
*
* Attempt to load the handler code (try different directories if not found).
* Call the handler's setup routine and get the HandlerData pointer.
* Check the version of the handler to be sure it's OK to use with this
* loader. Set the Segment and ParentTask pointer of the HandlerData.
*/
static void LoadIconify()
{
struct HandlerData *(*Setup)();
if ((Segment = LoadSeg(HANDLER)) == NULL)
if ((Segment = LoadSeg(handler)) == NULL)
DoExit("Can't load %s",handler);
Setup = (struct HandlerData *(*)()) ((Segment << 2) + 4);
HandlerData = (*Setup)(MAJLOADVERS,MINLOADVERS);
if (HandlerData)
{
if (var(MajVers) < MAJICONVERS ||
(var(MajVers) == MAJICONVERS && var(MinVers) < MINICONVERS))
DoExit("Version mismatch with %s",HANDLER);
} else {
DoExit("%s reports a version mismatch",HANDLER);
}
var(Segment) = Segment;
var(ParentTask) = FindTask(NULL);
}
/*
* CreateIconify()
*
* Once the handler is loader, attempt to create a process from it.
* Get a pointer to the handler process, and clear its console task
* since inheriting this pointer can cause errors in the NewCLI command.
* (this is a kludge, and should really be done by CreateProc()).
* Wait for the handler to signal that it is ready to go, or for a user
* initiated cancel.
*/
static void CreateIconify()
{
ULONG Signal;
int Pri = IconifyPriority;
static char *HandlerName = " wIconify-Handler ";
if (CreateProc(HandlerName,Pri,Segment,STACKSIZE) == NULL)
DoExit("Can't create wIconify-Handler process");
HandlerTask = FindTask(HandlerName);
if (HandlerTask == NULL) DoExit("Can't Find Handler Task");
HANDLERPROC->pr_ConsoleTask = NULL;
Signal = Wait(OKSIGNAL| CANCELSIGNAL);
if (Signal & CANCELSIGNAL)
DoExit("wIconify-Handler can't be initialized");
}
/*
* ActivateIconify()
*
* Signal the handler that it can proceed, and set the flags so that
* DoExit() knows that everything went smoothly (i.e., so that it will
* not free the allocated memory, etc).
*/
static void ActivateIconify()
{
Signal(HandlerTask,OKSIGNAL);
HandlerTask = NULL; Segment = NULL;
HandlerAdded = FALSE; VectorsSet = FALSE;
IntuitionBase = NULL;
GfxBase = NULL;
LayersBase = NULL;
AllOK = TRUE;
}
/*
* SetupScreens()
*
* Look through the intuition list of screens and call the handler's
* OpenScreen code for each one. This causes each screen to be processed
* by the handler as though it were just openned, hence it will get a
* backdrop wIconify window, etc.
*/
static void SetupScreens()
{
struct Screen *theScreen;
void (*cOpenScreen)() = var(cOpenScreen);
Forbid();
theScreen = IntuitionBase->FirstScreen;
while (theScreen)
{
(*cOpenScreen)(theScreen);
theScreen = theScreen->NextScreen;
}
Permit();
}
/*
* main()
*
* if wIconify is already running, then
* Attempt to end wIconify.
* If contact was made, wait for wIconify to confirm that it is done.
* If the user cancelled the wait, print a message,
* Otherwise, get the initialized variables for clean up
* Otherwise, wIconify is not already running, so
* Check if the program was called correctly
* Load the handler code,
* Get the variables needed for setup
* Open the libraries
* Read the init file, if any
* Set the default values for anything not defined in the file
* Set the variables to their initialized values
* Create the iconify task
* Have the handler process all the existing screens
* Add the Input Device handler and set the function traps
* Report that wIconify is installed.
* Exit with clean up
*/
void main(argc,argv)
int argc;
char **argv;
{
ULONG Signals;
extern struct HandlerData *wEndIconify();
if (wIconifyActive())
{
HandlerData = wEndIconify();
if (HandlerData == NULL) DoExit("Can't get HandlerData from Handler");
printf("Requesting wIconify to stop...");
Signals = Wait(OKSIGNAL| CANCELSIGNAL);
if ((Signals & CANCELSIGNAL) == FALSE)
GetIconifyVars(), printf("\n");
else
printf("[Cancelled]\n");
} else {
if (argc > 2) DoExit("Usage: '%s'",USAGE);
LoadIconify();
GetVariables();
CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
CheckLibOpen(&LayersBase,"layers.library",LAYERS_REV);
if (argc == 2) ReadInitFile(argv[1],NULL);
else ReadInitFile(INITFILENAME1,INITFILENAME2);
SetDefaults();
SetVariables();
CreateIconify();
SetupScreens();
if (TellInputDevice(IND_ADDHANDLER)) HandlerAdded = TRUE;
else DoExit("Can't add Input Handler");
SetVectors();
ActivateIconify();
printf("%s v%d.%d.%d installed\n",
program,var(MajVers),var(MinVers),MAJLOADVERS);
}
DoExit(NULL);
}